﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Reflection;
using Zhuang.Utility.Common.WinOS;

namespace Zhuang.Utility.Common.Entity
{
    /// <summary>
    /// DataTable与实体类互相转换
    /// </summary>
    /// <typeparam name="T">实体类</typeparam>
    public class EntityHelper<T> where T : new()
    {
        #region DataTable转换成实体类

        /// <summary>
        /// 填充对象列表：用DataSet的第一个表填充实体类
        /// </summary>
        /// <param name="ds">DataSet</param>
        /// <returns></returns>
        public static List<T> FillEntity(DataSet ds)
        {
            if (ds == null || ds.Tables[0] == null || ds.Tables[0].Rows.Count == 0)
            {
                return null;
            }
            else
            {
                return FillEntity(ds.Tables[0]);
            }
        }

        /// <summary>  
        /// 填充对象列表：用DataSet的第index个表填充实体类
        /// </summary>  
        public static List<T> FillEntity(DataSet ds, int index)
        {
            if (ds == null || ds.Tables.Count <= index || ds.Tables[index].Rows.Count == 0)
            {
                return null;
            }
            else
            {
                return FillEntity(ds.Tables[index]);
            }
        }

        /// <summary>  
        /// 填充对象列表：用DataTable填充实体类
        /// </summary>  
        public static List<T> FillEntity(DataTable dt)
        {
            if (dt == null || dt.Rows.Count == 0)
            {
                return null;
            }
            List<T> entityList = new List<T>();
            foreach (DataRow dr in dt.Rows)
            {
                //T entity = (T)Activator.CreateInstance(typeof(T));  
                T entity = new T();
                for (int i = 0; i < dr.Table.Columns.Count; i++)
                {
                    PropertyInfo propertyInfo = entity.GetType().GetProperty(dr.Table.Columns[i].ColumnName);
                    if (propertyInfo != null && dr[i] != DBNull.Value)
                        propertyInfo.SetValue(entity, dr[i], null);
                }

                entityList.Add(entity);
            }
            return entityList;
        }

        /// <summary>  
        /// 填充对象：用DataRow填充实体类
        /// </summary>  
        public static T FillEntity(DataRow dr)
        {
            if (dr == null)
            {
                return default(T);
            }

            //T entity = (T)Activator.CreateInstance(typeof(T));  
            T entity = new T();

            for (int i = 0; i < dr.Table.Columns.Count; i++)
            {
                PropertyInfo propertyInfo = entity.GetType().GetProperty(dr.Table.Columns[i].ColumnName);
                if (propertyInfo != null && dr[i] != DBNull.Value)
                    propertyInfo.SetValue(entity, dr[i], null);
            }
            return entity;
        }

        #endregion

        #region 实体类转换成DataTable

        /// <summary>
        /// 实体类转换成DataSet
        /// </summary>
        /// <param name="entityList">实体类列表</param>
        /// <returns></returns>
        public static DataSet FillDataSet(List<T> entityList)
        {
            if (entityList == null || entityList.Count == 0)
            {
                return null;
            }
            else
            {
                DataSet ds = new DataSet();
                ds.Tables.Add(FillDataTable(entityList));
                return ds;
            }
        }

        /// <summary>
        /// 实体类转换成DataTable
        /// </summary>
        /// <param name="entityList">实体类列表</param>
        /// <returns></returns>
        public static DataTable FillDataTable(List<T> entityList)
        {
            if (entityList == null || entityList.Count == 0)
            {
                return null;
            }
            DataTable dt = CreateData(entityList[0]);

            foreach (T entity in entityList)
            {
                DataRow dataRow = dt.NewRow();
                foreach (PropertyInfo propertyInfo in typeof(T).GetProperties())
                {
                    dataRow[propertyInfo.Name] = propertyInfo.GetValue(entity, null);
                }
                dt.Rows.Add(dataRow);
            }
            return dt;
        }

        /// <summary>
        /// 根据实体类得到表结构
        /// </summary>
        /// <param name="entity">实体类</param>
        /// <returns></returns>
        private static DataTable CreateData(T entity)
        {
            DataTable dataTable = new DataTable(typeof(T).Name);
            foreach (PropertyInfo propertyInfo in typeof(T).GetProperties())
            {
                dataTable.Columns.Add(new DataColumn(propertyInfo.Name, propertyInfo.PropertyType));
            }
            return dataTable;
        }

        #endregion


        /// <summary>
        /// 根据实体类得到Update语句
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static string GetUpdateSql(T entity)
        {
            Type type = typeof(T);
            PropertyInfo[] properties = type.GetProperties();

            string tbName = ConvertClassNameToTableName(type.Name);
            string strSql = "Update " + tbName + " set ";
            string idName = "";
            foreach (PropertyInfo pi in properties)
            {
                if (pi.Name.Trim().ToLower() == (tbName + "Id").ToLower())
                {
                    idName = pi.Name;
                    continue;
                }

                strSql = strSql + pi.Name + "='" + ReflectionHelper.GetProperty(entity, pi.Name) + "',";
            }

            strSql = strSql.Substring(0, strSql.Length - 1);

            strSql = strSql + " where " + idName + "=" + ReflectionHelper.GetProperty(entity, idName) ;

            return strSql;

        }

        /// <summary>
        /// 根据实体类得到Insert语句
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static string GetInsertSql(T entity)
        {
            Type type = typeof(T);
            PropertyInfo[] properties = type.GetProperties();

            string tbName = ConvertClassNameToTableName(type.Name);
            string strSql = "Insert into " + tbName +"(";
            string idName = "";
            foreach (PropertyInfo pi in properties)
            {
                if (pi.Name.Trim().ToLower() == (tbName + "Id").ToLower())
                {
                    idName = pi.Name;
                    continue;
                }

                strSql = strSql + pi.Name + ",";
            }

            strSql = strSql.Substring(0, strSql.Length - 1);

            strSql = strSql + ") values(";


            foreach (PropertyInfo pi in properties)
            {
                if (pi.Name.Trim().ToLower() == (tbName + "Id").ToLower())
                {
                    idName = pi.Name;
                    continue;
                }

                strSql = strSql +"'"+ ReflectionHelper.GetProperty(entity, pi.Name) + "',";
            }
            strSql = strSql.Substring(0, strSql.Length - 1);

            strSql = strSql + ")";


            return strSql;

        }


        /// <summary>
        /// 根据实体类得到Select语句
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static string GetSelectSql(T entity) 
        {

            Type type = typeof(T);
            PropertyInfo[] properties = type.GetProperties();
            string tbName = ConvertClassNameToTableName(type.Name);
            string strSql = "select {0} from " + tbName+" where {1}={2}";
            string strSelect = "";
            string idName = "";
            foreach (PropertyInfo pi in properties)
            {
                if (pi.Name.Trim().ToLower() == (tbName + "Id").ToLower())
                {
                    idName = pi.Name;
                   
                }

                strSelect = strSelect + pi.Name + ",";
            }
            strSelect = strSelect.Substring(0, strSelect.Length - 1);

            strSql = string.Format(strSql,strSelect,idName,ReflectionHelper.GetProperty(entity,idName));

            return strSql;
        }

        /// <summary>
        /// 根据实体类得到Delete语句
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static string GetDeleteSql(T entity)
        {

            Type type = typeof(T);
            
            string tbName = ConvertClassNameToTableName(type.Name);

            string idName = "";
            string strSql = "delete from " + tbName + " where {0}={1}";
            PropertyInfo[] properties = type.GetProperties();
            foreach (PropertyInfo pi in properties)
            {
                if (pi.Name.Trim().ToLower() == (tbName + "Id").ToLower())
                {
                    idName = pi.Name;
                    break;
                }
            }
            strSql=string.Format(strSql,idName,ReflectionHelper.GetProperty(entity,idName));

            return strSql;
        }


        private static string ConvertClassNameToTableName(string className)
        {
            return className.Replace("Entity", "");
        }
    } 

}
